package com.xiaoyi.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiaoyi.entity.*;
import com.xiaoyi.service.SysRoleService;
import com.xiaoyi.service.SysUserRoleService;
import com.xiaoyi.service.SysUserService;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.util.*;

/**
 * @author 小易
 * @version 1.0
 * @description TODO
 * @date 2022/12/14 11:32
 */
@RestController
@RequestMapping("/sys/user")
public class SysUserController {

    @Resource
    private SysUserService userService;

    @Resource
    private SysRoleService roleService;

    @Resource
    private SysUserRoleService userRoleService;

    @Resource
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Value("${avatarImagesFilePath}")
    private String avatarImagesFilePath;

    /**
     * @description 添加或修改用户信息
     * @param user 用户信息
     * @return com.xiaoyi.entity.ResultBody
     * @author 小易
     * @date 2022/12/14 11:35
     */
    @PostMapping("/save")
    @PreAuthorize("hasAuthority('system:user:add') || hasAuthority('system:user:edit')")
    public ResultBody save(@RequestBody SysUser user){
        if (user.getId() == null || user.getId() == -1){
            user.setCreateTime(new Date());
            user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
            userService.save(user);
        }else {
            user.setUpdateTime(new Date());
            userService.updateById(user);
        }
        return ResultBody.success();
    }

    /**
     * @description 批量删除
     * @param ids id列表
     * @return com.xiaoyi.entity.ResultBody
     * @author 小易
     * @date 2022/12/15 16:36
     */
    @Transactional
    @PostMapping("/delete")
    @PreAuthorize("hasAuthority('system:user:delete')")
    public ResultBody delete(@RequestBody Long[] ids){
        userService.removeByIds(Arrays.asList(ids));
        userRoleService.remove(new QueryWrapper<SysUserRole>().in("user_id", ids));
        return ResultBody.success();
    }

    /**
     * @description 根据条件分页查询用户信息列表
     * @param pageBean 分页参数
     * @return com.xiaoyi.entity.ResultBody
     * @author 小易
     * @date 2022/12/14 16:11
     */
    @GetMapping("/list")
    @PreAuthorize("hasAuthority('system:user:query')")
    public ResultBody list(PageBean pageBean){
        String query = pageBean.getQuery();
        Page<SysUser> page = userService.page(new Page<>(pageBean.getPageNum(), pageBean.getPageSize()), new QueryWrapper<SysUser>().like(StringUtils.hasText(query),"username",query));
        List<SysUser> userList = page.getRecords();

        for (SysUser user : userList) {
            List<SysRole> roleList = roleService.list(new QueryWrapper<SysRole>().inSql("id", "SELECT role_id FROM sys_user_role WHERE user_id = " + user.getId()));
            user.setRoleList(roleList);
        }

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("userList", userList);
        resultMap.put("total", page.getTotal());
        return ResultBody.success(resultMap);
    }

    /**
     * @description 根据id查询用户信息
     * @param id 用户id
     * @return com.xiaoyi.entity.ResultBody
     * @author 小易
     * @date 2022/12/15 14:19
     */
    @GetMapping("/{id}")
    @PreAuthorize("hasAuthority('system:user:query')")
    public ResultBody findById(@PathVariable("id") Integer id){
        SysUser userInfo = userService.getById(id);
        return ResultBody.success(userInfo);
    }

    /**
     * @description 检查是否有重名
     * @param user 用户名
     * @return com.xiaoyi.entity.ResultBody
     * @author 小易
     * @date 2022/12/15 16:34
     */
    @PostMapping("/checkUserName")
    @PreAuthorize("hasAuthority('system:user:query')")
    public ResultBody checkUserName(@RequestBody SysUser user){
        SysUser byUsername = userService.getByUsername(user.getUsername());
        if (byUsername != null) return ResultBody.error("用户名已存在！");
        return ResultBody.success();
    }

    /**
     * @description 修改指定用户的状态
     * @param id 用户id
     * @param status 状态
     * @return com.xiaoyi.entity.ResultBody
     * @author 小易
     * @date 2022/12/15 16:40
     */
    @GetMapping("/updateStatus/{id}/{status}")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public ResultBody updateStatus(@PathVariable("id") Integer id,@PathVariable("status") String status){
        SysUser user = userService.getById(id);
        user.setStatus(status);
        userService.updateById(user);
        return ResultBody.success();
    }

    /**
     * @description 修改密码
     * @param user 用户信息
     * @return com.xiaoyi.entity.ResultBody
     * @author 小易
     * @date 2022/12/14 16:03
     */
    @PostMapping("/updateUserPwd")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public ResultBody updateUserPwd(@RequestBody SysUser user){
        SysUser sqlUser = userService.getById(user.getId());
        if(bCryptPasswordEncoder.matches(user.getOldPassword(), sqlUser.getPassword())){
            sqlUser.setPassword(bCryptPasswordEncoder.encode(user.getNewPassword()));
            sqlUser.setUpdateTime(new Date());
            userService.updateById(sqlUser);
            return ResultBody.success();
        }else {
            return ResultBody.error("旧密码错误！");
        }
    }

    /**
     * @description 重置密码
     * @param id 用户id
     * @return com.xiaoyi.entity.ResultBody
     * @author 小易
     * @date 2022/12/15 16:33
     */
    @GetMapping("/resetPassword/{id}")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public ResultBody resetPassword(@PathVariable("id") Integer id){
        SysUser user = userService.getById(id);
        user.setPassword(bCryptPasswordEncoder.encode("123456"));
        userService.updateById(user);
        return ResultBody.success();
    }

    /**
     * @description 上传头像
     * @param file 头像文件
     * @return com.xiaoyi.entity.ResultBody
     * @author 小易
     * @date 2022/12/14 16:04
     */
    @PostMapping("/uploadImage")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public ResultBody uploadImage(@RequestParam("file") MultipartFile file) throws Exception{
        Map<String,Object> resultMap=new HashMap<>();
        if (file != null && !file.isEmpty()){
            String originalFilename = file.getOriginalFilename();
            assert originalFilename != null : "文件名为空！";
            String suffixName = originalFilename.substring(originalFilename.lastIndexOf("."));
            String newFileName = new Date().getTime() + suffixName;
            FileUtils.copyInputStreamToFile(file.getInputStream(), new File(avatarImagesFilePath + newFileName));
            resultMap.put("title",newFileName);
            resultMap.put("src","image/userAvatar/"+newFileName);
            return ResultBody.success(resultMap);
        }
        return ResultBody.error("上传文件失败，文件丢失！");
    }

    /**
     * @description 修改用户头像
     * @param user 用户信息
     * @return com.xiaoyi.entity.ResultBody
     * @author 小易
     * @date 2022/12/14 16:04
     */
    @PostMapping("/updateAvatar")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public ResultBody updateAvatar(@RequestBody SysUser user){
        userService.updateById(user);
        return ResultBody.success();
    }

    /**
     * @description 修改用户角色
     * @param userId 用户id
     * @param roleIdList 用户的角色列表
     * @return com.xiaoyi.entity.ResultBody
     * @author 小易
     * @date 2022/12/16 11:49
     */
    @Transactional
    @PostMapping("/grantRoles/{userId}")
    @PreAuthorize("hasAuthority('system:user:role')")
    public ResultBody grantRole(@PathVariable("userId") Long userId, @RequestBody Long[] roleIdList){
        List<SysUserRole> userRoleList = new ArrayList<>();
        for (Long roleId : roleIdList) {
            SysUserRole sysUserRole = new SysUserRole();
            sysUserRole.setUserId(userId);
            sysUserRole.setRoleId(roleId);
            userRoleList.add(sysUserRole);
        }
        userRoleService.remove(new QueryWrapper<SysUserRole>().eq("user_id", userId));
        userRoleService.saveBatch(userRoleList);
        return ResultBody.success();
    }

}
